<?php
/**
 * 单号生成
 * @author  yu
 */
namespace utils\x1;

use herosphp\core\Loader;


class MyNumber
{
    protected $primaryId;//主键自增id
    protected $cate_arr = array("dd", "ht", "xs", "fh", "th");//订单号，合同单号，销售单号，发货单号，提货单
    protected $number_arr = array("dd" => "dd_max", "ht" => "ht_max", "xs" => "xs_max", "fh" => "fh_max", "th" => "th_max");//单号类型与数据表中对于的字段名
    protected $prefx_arr = array("dd" => "DD", "ht" => "HT", "xs" => "XS", "fh" => "FH", "th" => "TH");//单号类型对应单号前缀

    public function __construct($app_id)
    {
        if ($app_id == '') {

            throw new \Exception('缺少appid');
        }
        $this->primaryId = $this->getPrimaryIdByAppId($app_id);

    }

    /**
     * 获取单号
     *
     * param string $cate 单号类型
     *
     * return string 返回单号
     */
    public function build_no($cate, $counts = '')
    {

        if (!in_array($cate, $this->cate_arr)) {

            return '';

        }

        $number = $this->getPrefx($cate) . $this->getPart1() . $this->getPart2($this->primaryId) . $this->getPart3($cate);

        if ($this->exist_no($cate, $number)) {

            $counts++;

            return ($counts < 5) ? $this->build_no($cate, $counts) : '';

        } else {

            return $number;
        }
    }

    //根据appid获取主键id
    private function getPrimaryIdByAppId($app_id)
    {

        $model = Loader::model('maxNo');

        $item = $model->getItem(array("app_id" => $app_id));

        if (isset($item) && $item['id'] > 0) {
            //有就返回主键id
            return $item['id'];

        } else {
            //没有则插入一条新数据
            return $this->insertRowByAppId($app_id);
        }

    }

    //给供应商插入一条max_no数据
    private function insertRowByAppId($app_id)
    {

        $model = Loader::model('maxNo');
        $last_id = $model->add(array(
            'dd_max' => 1,
            'ht_max' => 1,
            'xs_max' => 1,
            'fh_max' => 1,
            'th_max' => 1,
            'date' => date('Y-m-d'), 'app_id' => $app_id
        ));//,

        return $last_id;

    }

    //获取当天的流水id
    private function getPid($number_key, $date)
    {
        if (!($this->primaryId > 0)) {

            return false;
        }
        //获取数据库中的字段名
        $number_name = $this->number_arr[$number_key];

        $model = Loader::model('maxNo');

        $model->beginTransaction();

        //生成序列号时，每次读取该表，从该表中读取该行数据
        //每次读取的时候给该行使用FOR UPDATE上锁：
        $items = $model->query("select $number_name,date from max_no where id=" . $this->primaryId . " FOR UPDATE");

        if (empty($items[0])) {

            $model->rollback();
        }

        if ($items[0]['date'] == $date) {

            $bool = $model->increase($number_name, 1, $this->primaryId);

            $bool ? $model->commit() : $model->rollback();

            return $items[0][$number_name]+1;


        } else {

            $number_value=1;//初始当天开始计数

            $bool = $model->updates(array("date" => date('Y-m-d'), $number_name => $number_value), array("id" => $this->primaryId));

            $bool ? $model->commit() : $model->rollback();

            return $number_value;

        }

    }

    //前缀
    private function getPrefx($cate)
    {
        return $this->prefx_arr[$cate];
    }

    //第一部分 161102
    private function getPart1()
    {
        $today = substr(date('Ymd'), 2);
        return $today;
    }

    //第二部分 00001
    private function getPart2($id)
    {
        return str_pad($id, 5, "0", STR_PAD_LEFT);//低于5位，在前面补0，并和时间串连起来
    }

    //第三部分 000001
    private function getPart3($cate)
    {
        $today = date('Y-m-d');
        return str_pad($this->getPid($cate, $today), 6, "0", STR_PAD_LEFT);//低于6位，在前面补0，并和时间串连起来

    }


    /**
     * 判断单号是否存在于数据表中
     * @param $cate
     * @param $number
     */
    public function exist_no($cate, $number)
    {

        switch ($cate) {
            case 'dd':
                $this->exist_dd_no($number);
                break;
            case 'ht':
                $this->exist_ht_no($number);
                break;
            case 'xs':
                $this->exist_xs_no($number);
                break;
            case 'fh':
                $this->exist_fh_no($number);
                break;
            case 'th':
                $this->exist_th_no($number);
                break;
        }
    }

    //判断订单号是否存在
    public function exist_dd_no($no)
    {

        $model = Loader::model('tradingOrder');

        return $model->getItem(array("order_no" => $no), "id") ? true : false;

    }

    public function exist_ht_no($no)
    {

        $model = Loader::model('tradingContract');

        return $model->getItem(array("contract_no" => $no), "id") ? true : false;
    }

    public function exist_xs_no($no)
    {

        $model = Loader::model('tradingSale');

        return $model->getItem(array("sale_no" => $no), "id") ? true : false;

    }

    public function exist_fh_no($no)
    {

        $model = Loader::model('tradingInvoice');

        return $model->getItem(array("invoice_no" => $no), "id") ? true : false;
    }

    public function exist_th_no($no)
    {

        $model = Loader::model('tradingOrderLading');

        return $model->getItem(array("lading_no" => $no), "id") ? true : false;
    }
}
